package com.plum.admin.modules.common;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.plum.admin.common.annotation.RaterLimit;
import com.plum.admin.common.lock.Callback;
import com.plum.admin.common.lock.RedisLockTemplate;
import com.plum.admin.common.util.R;
import com.plum.admin.modules.card.entity.SysCard;
import com.plum.admin.modules.card.service.ISysCardService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * TODO
 *
 * @author 子丶沫
 * @version 1.0
 * @date 2021/8/13 15:35
 */
@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {
    @Autowired
    private RedissonClient redisson;
    @Autowired
    private RedisLockTemplate redisLockTemplate;
    @Autowired
    private ISysCardService cardService;

    @GetMapping("/noLogin")
    public R<Object> noLogin(){
        return R.error("您还未登录");
    }

    @GetMapping("/test")
    @RaterLimit(rate = 1,rateInterval = 5000)
    public R<Object> test(){

        return R.ok();
    }
    @RequestMapping(value = "/lockAndLimit", method = RequestMethod.GET)
    @ApiOperation(value = "同步锁限流测试")
    @ResponseBody
    public R<Object> test1() {

        redisLockTemplate.execute("订单流水号", 3, null, TimeUnit.SECONDS, new Callback() {
            @Override
            public Object onGetLock() {
                // TODO 获得锁后要做的事
                log.info("生成订单流水号");
                SysCard cards = cardService.getOne(Wrappers.<SysCard>lambdaQuery().orderByDesc(SysCard::getCreateTime).last("limit 1"));
                int no=1;
                if(!Objects.isNull(cards)){
                    Integer cardNo =Integer.valueOf( cards.getCardNo());
                    no=++cardNo;
                }
                try{
                    Thread.sleep(2000);
                }catch (Exception e){
                    e.printStackTrace();
                }
                SysCard card=new SysCard();
                card.setCardNo(String.valueOf(no));
                card.setCardName("体检卡");
                card.setCardType(1);
                card.setCreateTime(LocalDateTime.now());
                cardService.save(card);
                return null;
            }

            @Override
            public Object onTimeout() {
                // TODO 未获取到锁（获取锁超时）后要做的事
                log.info("oops 没拿到锁");
                try {
                    TimeUnit.NANOSECONDS.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });

        return R.ok(null);
    }
}
